Bash and Windows

From FVue
Jump to: navigation, search

As far as I'm concerned, the death of DOS batch files has been greatly exaggerated. Running a batch file is still the only way to perform a series of actions without the help of either third-party software or a macro-running behemoth like Word, Excel or the Windows Scripting language.

Don't bother to learn yet another Microsoft scripting invention, be it batch files, VBScript, Windows Scripting Language or - the latest - Windows PowerShell. Meet bash, where your knowledge is here to stay, since 1978!

Bash is part of a wide set of tools - the GNU development tools - which have been ported to MS-DOS and Windows systems. This page shows you how to hook bash into the Windows operating system. So you'll be familiar with bash once Linux breaks through ;-)

Freddy Vulto

Where To Get Bash For Windows?

Bash, short for GNU Bourne-Again SHell, is a sh-compatible command language interpreter that executes commands read from the standard input or from a file. Bash is a part of the GNU software collection, utilizing this collection to reach its full potential. The GNU software is an essential part of the Linux operating system, but is also available on the Windows operating system.

You can choose from a number of distributions - see Choices - but I suggest Cygwin because its large amount of additional useful programs - wget, ssh, X and w3m, just to name a few.

The next part of this article assumes you're using Cygwin.

Installing Cygwin

The url http://www.cygwin.com will contain a link to a downloadable setup.exe which will guide you through the process of downloading and installing Cygwin. Take care when installing everything: I had to clean up my harddisk to make room for the hundreds of megabytes...

Here you can find my list of additional packages I install besides the default packages.

Configuring Bash

cygwin.bat

The standard Cygwin installation provides this file cygwin.bat:

@echo off

C:
chdir C:\cygwin\bin

bash --login -i

Modify cygwin.bat to contain the following commands:

Windows 2000

@echo off
REM --- cygwin.bat ------------------------------------------------------------
REM function: Start Cygwin
REM args:     - 1..9: bash shell arguments

C:\cygwin\bin\bash --login -i %1 %2 %3 %4 %5 %6 %7 %8 %9

Create an additional batch file cygwin_here.bat:

@echo off
REM --- cygwin_here.bat ------------------------------------------------------
REM function: Start Cygwin in current directory
REM args:     - 1..9

REM Setting `CHERE_INVOKING' prevents /etc/profile from issuing `cd $HOME'
set CHERE_INVOKING=1
C:\cygwin\bin\bash --login -i %1 %2 %3 %4 %5 %6 %7 %8 %9

Windows 95/98

The bash shell runs on top of command.com. In order to meet bash' rather large demand of environment space, it's often necessary to enlarge this space by specifying /e:<number> to command.com. Although this can be done by putting SHELL= in config.sys, I dislike messing with autoexec.bat and config.sys, so I'm starting bash from a preliminary batch file cygwin.bat which enlarges environment space. After the environment space is enlarged, a second batch file _cygwin.bat is called:

C:\cygwin\cygwin.bat -> C:\cygwin\_cygwin.bat -> bash.exe
@echo off
REM --- cygwin.bat ------------------------------------------------------------
REM function: Shell command.com in order to start Cygwin.
REM args:     1-9: bash shell arguments

   REM Shell command.com with enough environment space and start _cygwin.bat
command.com /e:1024 /k C:\cygwin\_cygwin.bat %1 %2 %3 %4 %5 %6 %7 %8 %9

The option /e:1024 gives me 4 times as much environment space as standard command.com which has the environment space set to 256 bytes. If you ever receive the error "Out of environment space", you're free to increase this number. The option /k _cygwin.bat tells command.com to start the batch file _cygwin.bat immediately after command.com is initialized. The arguments %1, %2, etc. will pass optional arguments (e.g. shell scripts) to bash.

@echo off
REM --- _cygwin.bat -----------------------------------------------------------
REM function: Start Cygwin
REM args:     - 1..9: bash shell arguments

C:\cygwin\bin\bash --login -i %1 %2 %3 %4 %5 %6 %7 %8 %9
exit

Additionally create two batch files cygwin_here.bat and _cygwin_here.bat to start cygwin in the current directory:

@echo off
REM --- cygwin_here.bat -------------------------------------------------------
REM function: Shell command.com in order to start Cygwin in current directory
REM args:     1-9: bash shell arguments

   REM Shell command.com with enough environment space and start _cygwin.bat
command.com /e:1024 /k C:\cygwin\_cygwin_here.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
@echo off
REM --- _cygwin_here.bat ------------------------------------------------------
REM function: Start Cygwin
REM args:     - 1..9: bash shell arguments

REM Setting `CHERE_INVOKING' prevents /etc/profile from issuing `cd $HOME'
set CHERE_INVOKING=1
C:\cygwin\bin\bash --login -i %1 %2 %3 %4 %5 %6 %7 %8 %9
exit

.alias, .bashrc, .inputrc

See Bash: My configuration

Configuring Windows

Start;Run

In order to be able to type either 'cygwin' or 'djgpp' from the Start;Run window, modify the registry like this:

HKEY_LOCAL_MACHINE
|-Software
  |-Microsoft
    |-Windows
      |-CurrentVersion
        |-App Paths
          |-cygwin.exe     C:\cygwin\cygwin.bat

DOS-box

In order to be able to run 'bash' from the DOS-box, add a batch file to the properties of the DOS-box via {Properties, tab 'Program', Batch file}, and let this batch file add the bash directory to the path:

PATH=D:\Programs\DjGpp;%PATH%

Folder Popup Menu

It would be nice if we could jumpstart bash from a specific folder name by selecting so from the folder's right-mousebutton-menu. Fortunately, Windows offers us the capabilities. Add the keys underneath to the registry. (Use the program regedit to modify the Windows registry)

Shell to Cygwin

HKEY_CLASSES_ROOT
|-Folder
  |-shell
    |-Shell to Cygwin   "Shell to Cyg&win"
      |-command         "C:\cygwin\cygwin_here.bat"

Shell to DOS

And while your at it:

    |-Shell to DOS     "Shell to DO&S"
      |-command        "C:\command.com /k cd %1"     (Windows 95)
                       "C:\command.com"              (Windows 98)
                       "C:\WINNT\cmd.exe"            (Windows NT)
                       "C:\WINNT\system32\cmd.exe"   (Windows 2000)

Shell Script Automation

It would be nice if shell scripts could be run by doubleclicking on them or by specifying them via {Start; Run}. Also it would be convenient if shell scripts could be editted by selecting so from the popup menu. These are the necessary registry items to accomplish all this:

HKEY_CLASSES_ROOT
|-.sh                  "Bash.Shell.Script"
:
|-Bash.Shell.Script
  |-shell
    |-edit             "&Edit"
    | |-command        "notepad.exe "%1""
    |-open             "&Run"
      |-command        "C:\cygwin\cygwin.bat "%1" "%2" "%3" "%4" "%5" "%6" "%7" "%8" "%9""

Terminal colors

The default color scheme of the Windows console window can do with some improvements:

  1. Select the system menu by pressing ALT-TAB or by clicking the upper-left window icon
  2. Select {Properties | Colors}
  3. To make blue text readable on a dark background: Select second color (blue) and set the RGB values to 20, 104, 178.
  4. To make gray text less contrasting to the dark background: Select eight color (light gray) and set the RGB value to 178, 178, 178.
  5. Pair `Screen text' to `light gray' (eight color)
  6. Pair `Screen background' to `black' (first color)
  7. Select `OK', `Save properties for next windows with the same name', `OK'

For another console, see:

http://sourceforge.net/projects/console/
"Console is a Windows console window enhancement. Console features include: multiple tabs, text editor-like text selection, different background types, alpha and color-key transparency, configurable font, different window styles"

Configuring Applications

Bash completion

The standard single file bash completion package which comes with Cygwin is rather slow. You can get bash completion 5-10 times as fast by installing an alternative: bash_completion_library.

Microsoft Developer Studio

The C++ IDE of Microsoft's Developer Studio offers you the ability to execute 'Custom Build', 'Pre-link step' or 'Post-build step' commands. These can be bash commands as well. To show the standard output of bash in the 'Output' window of DevStudio, you have to redirect normal output to stderr, using redirection symbol '>&2'. For example, suppose you want to execute the script C:\hello.sh as a Post-build step:

#!/bin/sh
#--- hello.sh ---------------------

echo "Hello World!" >&2

Start Developer Studio, select {Project;Settings}, go to the rightmost tab 'Post-build step' and type as 'Post-build command(s)':

C:\cygwin\cygwin.bat C:\hello.sh

Vim (gVim)

To set bash as the default shell of your GUI Vim, put the commands underneath in your _gvimrc file. Now you can type :sh[ell] to invoke bash, or :r !ls to insert the contents of the current directory, or :make to make your project.

   " Set shell to Cygwin bash
set shell=C:\\Cygwin\\cygwin.bat
   " Shell arguments; -c: argument
set shellcmdflag=-c
   " Shell redirect; copy stderr to stdout
set shellredir=>%s\ 2>&1
   " Shell pipe; copy stderr to stdout
set shellpipe=2>&1\|\ tee
   " Shell quote; embed command within quotes
set shellxquote=\"

Gotchas

More gotchas

Cygwin in a production environment? - 24x7 Slashdot post with lots of tips.

Subversion: Can't copy file: No error

When doing a subversion checkout from a Linux repository to a Windows/Cygwin working directory, you might receive the error:

svn: Can't copy file: No error

Next, the working directory is locked and a svn cleanup doesn't work.

Solution

Make sure the Linux repository isn't containing files with similar names but only differences in lowercase/uppercase letters, e.g. release/RELEASE/Release. Windows - contrary to Linux - treats filenames with different case as if it was one file - causing Subversion to generate the error.

getopt: command not found

When running a shell script, I received the error:

bash: getopt: command not found

It appears the `getopt' command is not ready available from Cygwin. And I can't find a package named `getopt' to install. Bash has a builtin `getopts', but this doesn't take care of long options.

Solution

Install the Cygwin package `util-linux'. This package provides `getopt.exe'.

Did you know you can search packages for a specific file with the command cygcheck -p command? This is how it goes:

$ cygcheck -p getopt.exe
Found 3 matches for getopt.exe.
util-linux/util-linux-2.12r-2   Random collection of Linux utilities
util-linux/util-linux-2.13.1-1  Random collection of Linux utilities
util-linux/util-linux-2.13.1-2  Random collection of Linux utilities

tar --exclude-from=FILE not working

Specifying exclude files in a separate file didn't work.

Solution

I created the FILE with vim for Windows and so the lines ended with CR/LF instead of a NL. After gaving the following command in Vim:

:set ff=unix

tar excluded the specified files all right.  Is this because I installed Cygwin with UNIX line-endings? Things would've worked as well also, if I'd used the Vim which comes with Cygwin.

Error '/usr/bin/pod2man: not found' using pod2usage()

Using the Pod::Usage function pod2usage() gave me the error:

/usr/bin/pod2man: not found

Solution

The problem occurred after I'd put CYGWIN=ntea into my .bashrc for testing purposes. Removing CYGWIN=ntea from my .bashrc made pod2man work all right again.

Bash: $'\r': command not found

When starting Cygwin, you might get many errors:

bash: $'\r': command not found

Solution

If you've edited a bash startup file like .bashrc or /etc/profile with a DOS-editor, the line endings might have changed to CR/LF instead of a single LF. This may cause the errors above. To fix these errors: edit the file with vim , give the command :set ff=unix and save the file.

Recode: Ambiguous output in step `data..CR-LF'

When converting character set of a file with recode, I received this error:

c:\WINNT\system32\recode.exe: Ambiguous output in step `data..CR-LF'

Solution

Convert line endings from CR/LF to a single LF: Edit the file with vim , give the command :set ff=unix and save the file. Recode now should run without errors.

Choices

Cygwin

Cygwin is

  • a Linux-like environment for Windows. It consists of two parts: A DLL (cygwin1.dll) which acts as a Linux API emulation layer providing substantial Linux API functionality.
  • A collection of tools which provide Linux look and feel.

DJGPP

DJGPP is a complete 32-bit C/C++ development system for Intel 80386 (and higher) PCs running DOS. It includes ports of many GNU development utilities. The development tools require a 80386 or newer computer to run, as do the programs they produce. In most cases, the programs it produces can be sold commercially without license or royalties.</p>

UnxUtils

This UnxUtils project collects some ports of common GNU utilities to native Win32. In this context, native means the executables do only depend on the Microsoft C-runtime (msvcrt.dll) and not an emulation layer like that provided by Cygwin tools.

coLinux

Cooperative Linux, a port of the Linux kernel that allows it to run as an unprivileged lightweight virtual machine in kernel mode, on top of another OS kernel.

SFU

SFU ("Microsoft Windows Services for UNIX") 3.5 includes Interix, a complete POSIX development environment integrated with the Windows kernel. Both Korn and C shells are included, and the Bash shell is available as a free download. Most of the UNIX utilities are available, but development support (gcc) seems to be lacking.

MinGW

MinGW ("Minimalistic GNU for Windows"): A collection of freely available and freely distributable Windows specific header files and import libraries combined with GNU toolsets that allow one to produce native Windows programs that do not rely on any 3rd-party C runtime DLLs. It compiles and links code to be run on Win32 platforms.

UWIN

The UWIN package allows UNIX applications to be built and run on Windows XP/2000/NT/ME/98/95 with few, if any, changes necessary. UWIN doesn't contain bash but ksh (the Korn Shell) instead.

WARNING: Google AdSense Unit ID "" does not exist.
Available Unit IDs: C01, C02, C03, C04, C05, C06, C07, C08, C09, C10, S01, S02, V01, V02, V03.
Example: <google uid="C01"></google>, <google uid="C01" position="left" ></google>

See also

<amazon name="carouselBashBooks" />

Journal

20071021

Removed modifications of /etc/profile. I'm not sure about the `id' command. The `cd $HOME' can nowadays be circumvented by setting `CHERE_INVOKING'.

#--- /etc/profile -------------------------------------------------------------
# function: Global bash initialization

PATH="/usr/local/bin:/usr/bin:/bin:$PATH"
unset DOSDRIVE
unset DOSDIR
unset TMPDIR
unset TMP

        # NOTE: I'm not using the 'id' command since this will return my Windows
        #       login name 'Freddy Vulto' with a space in it, which I'd like to
        #       avoid.  See Cygwin FAQ.
        #USER="`id -un`"
USER=FVu

        # Set up USER's home directory
if [ -z "$HOME" ]; then
  HOME="/home/$USER"
fi

if [ ! -d "$HOME" ]; then
  mkdir -p "$HOME"
fi

export HOME USER

for i in /etc/profile.d/*.sh ; do
  if [ -f $i ]; then
    . $i
  fi
done

export MAKE_MODE=unix
export PS1='\[\033]0;\w\007
\033[32m\]\u@\h \[\033[33m\w\033[0m\]
$ '

        # Execute commands from ~/.bashrc if file exists
test -f ~/.bashrc && . ~/.bashrc



This page is a rewrite of (now broken) http://home.wanadoo.nl/fvu/Projects/Bash/Web/bash.htm.

Comments

blog comments powered by Disqus